using System.Text;
using Gateway.IQuery.Language;
using Gateway.IQuery.Question;
using Gateway.IQuery.Webide.Request;
using Gateway.IQuery.Webide.Result;
using Microsoft.AspNetCore.Authorization;

namespace Gateway.UI.Api.Controllers;

/// <summary>
/// 
/// </summary>
[AllowAnonymous]
public class WebideController : BaseController
{
    private readonly IHttpClientFactory _clientFactory;
    private readonly string _api;
    private readonly ILanguageQuery _languageQuery;
    private readonly IQuestionQuery _questionQuery;
    private readonly ILogger<WebideController> _logger;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="clientFactory"></param>
    /// <param name="configuration"></param>
    /// <param name="languageQuery"></param>
    /// <param name="questionQuery"></param>
    /// <param name="logger"></param>
    public WebideController(IHttpClientFactory clientFactory, IConfiguration configuration,
        ILanguageQuery languageQuery, IQuestionQuery questionQuery, ILogger<WebideController> logger)
    {
        _clientFactory = clientFactory;
        _languageQuery = languageQuery;
        _questionQuery = questionQuery;
        _logger = logger;
        _api = configuration["WebideApiUrl"];
    }

    /// <summary>
    /// 获取试题
    /// </summary>
    /// <returns></returns>
    [HttpGet, Route("questions")]
    public async Task<List<WebIdeQuestionResult>> GetQuestionsAsync()
    {
        var httpclient = new System.Net.Http.HttpClient();
        var response = await httpclient.GetAsync(_api + "/question/list");

        var str = await response.Content.ReadAsStringAsync();

        var result = JsonConvert.DeserializeObject<WebIdeResult<List<WebIdeQuestionResult>>>(str);
        return result.Data;
    }

    /// <summary>
    /// 获取语言
    /// </summary>
    /// <returns></returns>
    [HttpGet, Route("langs")]
    public async Task<List<WebIdeLangResult>> GetLanguagesAsync(string questionKey)
    {
        var httpclient = new System.Net.Http.HttpClient();
        var response = await httpclient.GetAsync(_api + "/language?questionKey=" + questionKey);

        var str = await response.Content.ReadAsStringAsync();

        var result = JsonConvert.DeserializeObject<WebIdeResult<List<WebIdeLangResult>>>(str);
        return result.Data;
    }

    /// <summary>
    /// 运行语言
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    [HttpPost, Route("run")]
    public async Task<string> RunCode(WebideRunRequest request)
    {
        var lang = await _languageQuery.GetDetailByLang(request.Lan);
        if (lang == null)
            throw new MyException("运行语言无效");
        var question = await _questionQuery.GetDetail(request.QuestionKey, request.Lan);
        if (question == null)
        {
            throw new MyException("试题无效");
        }

        var language = question.Languages[0];
        //查询 依赖库
        var dependCodes = language.DependCodesList;
        List<ExtensionCodeConfig> dependCodeList = new List<ExtensionCodeConfig>();
        if (dependCodes.Count > 0)
        {
            var tmpExtensionCodes = await _languageQuery.GetLangExtensionCodeByIds(dependCodes);
            dependCodeList = tmpExtensionCodes.Select(p => new ExtensionCodeConfig()
            {
                Code = p.Code,
                Name = p.Name
            }).ToList();
        }

        var extensionCodes = dependCodeList;
        if (language.ExtensionCodes?.Count > 0)
        {
            extensionCodes.AddRange(language.ExtensionCodes.Select(p => new ExtensionCodeConfig()
            {
                Code = p.Code, Name = p.Name
            }).ToList());
        }

        var newRequest = new LanguageRunExampleRequest
        {
            Config = new LanguageConfig()
            {
                // Build = lang.Build,
                BuildCommand = lang.BuildCommand,
                // Exec = lang.Exec,
                ImageName = lang.Exec,
                ExecCommand = lang.ExecCommand,
                Lang = lang.Lang,
                LangType = lang.LangType,
            },

            QuestionConfig = new LanguageExampleConfig()
            {
                File = language.ExamplesFileName,
                ExecFile = language.ExecFileName,
                ExtensionCodes = extensionCodes,
                TestCase = question.QuestionCaseList?.Select(p => p.Case).ToList() ?? new List<string>(),
                Answer = question.QuestionCaseList?.Select(p => p.Target).ToList() ?? new List<string>(),
                Code = request.Code
            }
        };
        var val = JsonConvert.SerializeObject(newRequest);
        _logger.LogInformation("当前运行的请求参数为：" + val);
        HttpContent content =
            new StringContent(val, Encoding.UTF8, "application/json");
        try
        {
            // var httpclient = new Aurora.HttpClient();
            var httpclient = _clientFactory.CreateClient();
            var response = await httpclient.PostAsync(_api + "/Judge/RunCode", content);

            var str = await response.Content.ReadAsStringAsync();
            _logger.LogWarning("执行结果：" + str);
            var result = JsonConvert.DeserializeObject<WebIdeResult<string>>(str);
            //获取到 运行结果的查询标识
            return result?.Data ?? "";
        }
        catch (Exception e)
        {
            _logger.LogError(JsonConvert.SerializeObject(e));
            throw new MyException("执行出现异常");
        }
    }

    /// <summary>
    /// 获取到执行结果
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    [HttpGet, Route("result/{key}")]
    public async Task<RuntimeResult> GetRuntimeResult(string key)
    {
        var httpclient = _clientFactory.CreateClient();
        var response = await httpclient.GetAsync(_api + "/Judge/getResult/" + key);
        var str = await response.Content.ReadAsStringAsync();
        _logger.LogWarning("[代码结果] 获取到的结果为：" + str);
        var result = JsonConvert.DeserializeObject<WebIdeResult<RuntimeResult>>(str);
        return result?.Data;
    }
}